package com.mmall.service.impl;

import com.alipay.api.AlipayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.demo.trade.config.Configs;
import com.alipay.demo.trade.model.ExtendParams;
import com.alipay.demo.trade.model.GoodsDetail;
import com.alipay.demo.trade.model.builder.AlipayTradePrecreateRequestBuilder;
import com.alipay.demo.trade.model.result.AlipayF2FPrecreateResult;
import com.alipay.demo.trade.service.AlipayTradeService;
import com.alipay.demo.trade.service.impl.AlipayTradeServiceImpl;
import com.alipay.demo.trade.utils.ZxingUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mmall.common.IConst;
import com.mmall.common.ResponseInfo;
import com.mmall.common.ServerResponse;
import com.mmall.dao.*;
import com.mmall.pojo.*;
import com.mmall.service.IOrderService;
import com.mmall.util.BigDecimalUtil;
import com.mmall.util.DateTimeUtil;
import com.mmall.util.FTPUtil;
import com.mmall.util.PropertiesUtil;
import com.mmall.vo.OrderItemVo;
import com.mmall.vo.OrderProductVo;
import com.mmall.vo.OrderVo;
import com.mmall.vo.ShippingVo;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * 订单及支付宝管理逻辑层实现类
 * Created by qezhhnjy on 2017/10/6-15:21.
 */
@Service("iOrderService")
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class OrderServiceImpl implements IOrderService {

    private static final Logger log = LoggerFactory.getLogger(OrderServiceImpl.class);

    @Resource
    private OrderItemMapper orderItemMapper;

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private PayInfoMapper payInfoMapper;

    @Resource
    private CartMapper cartMapper;

    @Resource
    private ProductMapper productMapper;

    @Resource
    private ShippingMapper shippingMapper;

    //二维码当面支付
    @Override
    public ServerResponse pay(Integer userId, Long orderNo, String path) {
        if (userId == null || orderNo == null || StringUtils.isBlank(path))
            return ServerResponse.createByErrorCode(ResponseInfo.ILLEGAL_ARGUMENT.getCode(), ResponseInfo.ILLEGAL_ARGUMENT.getDescription());
        Order tempOrder = orderMapper.selectByUserIdOrderNo(userId, orderNo);
        if (tempOrder == null)
            return ServerResponse.createByErrorMessage("该用户没有该订单~!");
        Map<String, String> resultMap = Maps.newHashMap();
        resultMap.put("orderNo", String.valueOf(tempOrder.getOrderNo()));

        // (必填) 商户网站订单系统中唯一订单号，64个字符以内，只能包含字母、数字、下划线，
        // 需保证商户系统端不能重复，建议通过数据库sequence生成，
        String outTradeNo = tempOrder.getOrderNo().toString();

        // (必填) 订单标题，粗略描述用户的支付目的。如“xxx品牌xxx门店当面付扫码消费”
        String subject = String.format("happymmall扫码支付,订单号%s", outTradeNo);

        // (必填) 订单总金额，单位为元，不能超过1亿元
        // 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】
        String totalAmount = tempOrder.getPayment().toString();

        // (可选) 订单不可打折金额，可以配合商家平台配置折扣活动，如果酒水不参与打折，则将对应金额填写至此字段
        // 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】
        String undiscountableAmount = "0";

        // 卖家支付宝账号ID，用于支持一个签约账号下支持打款到不同的收款账号，(打款到sellerId对应的支付宝账号)
        // 如果该字段为空，则默认为与支付宝签约的商户的PID，也就是appid对应的PID
        String sellerId = "";

        // 订单描述，可以对交易或商品进行一个详细地描述，比如填写"购买商品2件共15.00元"
        String body = String.format("订单%s购买商品共%s元", orderNo, totalAmount);

        // 商户操作员编号，添加此参数可以为商户操作员做销售统计
        String operatorId = "test_operator_id";

        // (必填) 商户门店编号，通过门店号和商家后台可以配置精准到门店的折扣信息，详询支付宝技术支持
        String storeId = "test_store_id";

        // 业务扩展参数，目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法)，详情请咨询支付宝技术支持
        ExtendParams extendParams = new ExtendParams();
        extendParams.setSysServiceProviderId("2088100200300400500");

        // 支付超时，定义为120分钟
        String timeoutExpress = "120m";

        // 商品明细列表，需填写购买商品详细信息，
        List<GoodsDetail> goodsDetailList = new ArrayList<GoodsDetail>();
        // 创建一个商品信息，参数含义分别为商品id（使用国标）、名称、单价（单位为分）、数量，如果需要添加商品类别，详见GoodsDetail
        List<OrderItem> orderItems = orderItemMapper.selectByUserIdOrderNo(userId, orderNo);
        for (OrderItem orderItem : orderItems) {
            GoodsDetail tempGood = GoodsDetail.newInstance(orderItem.getProductId().toString(), orderItem.getProductName(),
                    BigDecimalUtil.multiply(orderItem.getCurrentUnitPrice().doubleValue(), 100d).longValue(), orderItem.getQuantity());
            goodsDetailList.add(tempGood);
        }

        // 创建扫码支付请求builder，设置请求参数
        AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder()
                .setSubject(subject).setTotalAmount(totalAmount).setOutTradeNo(outTradeNo)
                .setUndiscountableAmount(undiscountableAmount).setSellerId(sellerId).setBody(body)
                .setOperatorId(operatorId).setStoreId(storeId).setExtendParams(extendParams)
                .setTimeoutExpress(timeoutExpress)
                .setNotifyUrl(PropertiesUtil.getProperty("alipay.callback.url"))//支付宝服务器主动通知商户服务器里指定的页面http路径,根据需要设置
                .setGoodsDetailList(goodsDetailList);

        Configs.init("zfbinfo.properties");

        // 支付宝当面付2.0服务
        AlipayTradeService tradeService = new AlipayTradeServiceImpl.ClientBuilder().build();

        AlipayF2FPrecreateResult result = tradeService.tradePrecreate(builder);
        switch (result.getTradeStatus()) {
            case SUCCESS:
                log.info("支付宝预下单成功: )");

                AlipayTradePrecreateResponse response = result.getResponse();
                dumpResponse(response);

                //创建web目录下的二维码上级目录
                File folder = new File(path);
                if (!folder.exists()) {
                    folder.setWritable(true);
                    folder.mkdirs();
                }

                //设置二维码的缓存路径,和FTP路径并上传到FTP.
                String qrPath = String.format(path + "/qr-%s.png", response.getOutTradeNo());
                String qrFileName = String.format("qr-%s.png", response.getOutTradeNo());
                File targetFile = ZxingUtils.getQRCodeImge(response.getQrCode(), 256, qrPath);
                try {
                    FTPUtil.uploadFile(Lists.newArrayList(targetFile));
                } catch (IOException e) {
                    log.error("上传二维码异常~!", e);
                }
                log.info("qrPath:" + qrPath);

                String qrUrl = PropertiesUtil.getProperty("ftp.server.http.prefix") + qrFileName;
                resultMap.put("qrUrl", qrUrl);
                return ServerResponse.createBySuccess(resultMap);

            case FAILED:
                log.error("支付宝预下单失败!!!");
                return ServerResponse.createByErrorMessage("支付宝预下单失败!!!");

            case UNKNOWN:
                log.error("系统异常，预下单状态未知!!!");
                return ServerResponse.createByErrorMessage("系统异常，预下单状态未知!!!");

            default:
                log.error("不支持的交易状态，交易返回异常!!!");
                return ServerResponse.createByErrorMessage("不支持的交易状态，交易返回异常!!!");
        }
    }


    // 简单打印应答
    private void dumpResponse(AlipayResponse response) {
        if (response != null) {
            log.info(String.format("code:%s, msg:%s", response.getCode(), response.getMsg()));
            if (StringUtils.isNotEmpty(response.getSubCode())) {
                log.info(String.format("subCode:%s, subMsg:%s", response.getSubCode(),
                        response.getSubMsg()));
                System.out.println("--------------------------");
            }
            log.info("body:" + response.getBody());
        }
    }

    //处理支付宝回调信息
    @Override
    public ServerResponse aliCallback(Map<String, String> params) {
        //获取订单号
        Long orderNo = Long.valueOf(params.get("out_trade_no"));
        //获取订单的支付宝交易号
        String tradeNo = params.get("trade_no");
        //获取订单的交易状态
        String tradeStatus = params.get("trade_status");
        //查询该订单号的订单
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order == null)
            return ServerResponse.createByErrorMessage("非快乐慕商城的订单,回调忽略!");

        //这段代码是用于过滤重复调用.
        // 如果数据库中订单数据显示订单已付款/已发货/交易成功/交易关闭
        //则返回Success但支付宝重复调用的信息.
        //--注意这里时判定的数据库中查询到的订单信息,而不是回调过来的数据信息.--
        if (order.getStatus() >= IConst.OrderStatus.PAID.code)
            return ServerResponse.createBySuccessMessage("支付宝重复调用~!");

        if (IConst.AlipayCallback.TRADE_STATUS_TRADE_SUCCESS.equals(tradeStatus)) {
            //更新订单的交易状态,支付时间
            order.setStatus(IConst.OrderStatus.PAID.code);
            order.setPaymentTime(DateTimeUtil.strToDate(params.get("gmt_payment")));
            orderMapper.updateByPrimaryKeySelective(order);

            System.out.println("++++++");
            Order tempOrder = new Order();
            tempOrder.setId(order.getId());
            tempOrder.setPaymentTime(DateTimeUtil.strToDate(params.get("gmt_payment")));
            tempOrder.setStatus(IConst.OrderStatus.PAID.code);
            orderMapper.updateByPrimaryKeySelective(tempOrder);
        }

        PayInfo payInfo = new PayInfo();
        payInfo.setUserId(order.getUserId());
        payInfo.setOrderNo(orderNo);
        payInfo.setPayPlatform(IConst.Platform.ALIPAY.code);
        payInfo.setPlatformNumber(tradeNo);
        payInfo.setPlatformStatus(tradeStatus);

        payInfoMapper.insert(payInfo);

        return ServerResponse.createBySuccess();
    }

    //查询订单状态
    @Override
    public ServerResponse queryOrderPayStatus(Integer userId, Long orderNo) {
        Order order = orderMapper.selectByUserIdOrderNo(userId, orderNo);
        if (order == null)
            return ServerResponse.createByErrorMessage("该用户没有该订单~!");
        if (order.getStatus() >= IConst.OrderStatus.PAID.code)
            return ServerResponse.createBySuccess();
        return ServerResponse.createByError();
    }

    //通过用户id查找其完整购物车中勾选的购买商品和传入的收货地址创建订单.
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ)
    public ServerResponse createOrder(Integer userId, Integer shippingId) {
        //从购物车中获取数据
        List<Cart> carts = cartMapper.selectCheckedCartByUserId(userId);

        //这里我之前的想法是重用CartServiceImpl.java的getCartVoLimit方法.
        //但是老师是重新写了一个private方法进行封装.因为有些元素的判定还是与CartVo有些不同.
        //比如商品是否在售,CartVo中并没有判定,而生成订单则需要进行判定.

        ServerResponse<List<OrderItem>> cartOrderItems = getCartOrderItems(userId, carts);
        if (!cartOrderItems.isSuccess()) {
            return cartOrderItems;
        }
        List<OrderItem> orderItems = cartOrderItems.getData();

        //生成订单
        Order order = assembleOrder(userId, shippingId, orderItems);

        if (order == null) return ServerResponse.createByErrorMessage("生成订单错误~!");

        int insert = orderMapper.insert(order);

        if (insert == 1) System.out.println("生成订单成功！");

        //订单生成后,要对订单中的每个订单明细添加订单号
        for (OrderItem orderItem : orderItems)
            orderItem.setOrderNo(order.getOrderNo());

        //mybatis批量插入
        orderItemMapper.batchInsert(orderItems);

        //生成成功,减少商品的库存
        //老师选择在这里插入了新的减少库存的方法,我个人选择在封装订单明细集合时就清除库存.

        //清空购物车
        cleanCart(carts);

        //返回数据给前端
        OrderVo orderVo = assembleOrderVo(order, orderItems);
        return ServerResponse.createBySuccess(orderVo);
    }

    //取消订单
    @Override
    public ServerResponse<String> cancelOrder(Integer userId, Long orderNo) {
        Order order = orderMapper.selectByUserIdOrderNo(userId, orderNo);
        if (order == null) return ServerResponse.createByErrorMessage("该用户没有此订单！");
        //这里没有区分付款和取消，可能考虑到前端页面对于取消的订单不会设置取消按钮所以不需要判定取消。
        if (order.getStatus() != IConst.OrderStatus.NO_PAY.code)
            return ServerResponse.createByErrorMessage("已付款，无法取消订单！");

        Order tempOrder = new Order();
        tempOrder.setId(order.getId());
        tempOrder.setStatus(IConst.OrderStatus.CANCELED.code);

        return orderMapper.updateByPrimaryKeySelective(tempOrder) > 0 ?
                ServerResponse.createBySuccess() : ServerResponse.createByError();

    }

    @Override
    public ServerResponse<OrderProductVo> orderSimple(Integer userId) {
        OrderProductVo orderProductVo = new OrderProductVo();

        //从购物车中获取数据
        List<Cart> carts = cartMapper.selectCheckedCartByUserId(userId);

        ServerResponse<List<OrderItem>> cartOrderItems = getCartOrderItems(userId, carts);
        if (!cartOrderItems.isSuccess()) return ServerResponse.createByErrorMessage(cartOrderItems.getMsg());

        List<OrderItem> orderItems = cartOrderItems.getData();

        List<OrderItemVo> orderItemVos = Lists.newArrayList();

        BigDecimal payment = new BigDecimal("0");
        for (OrderItem orderItem : orderItems) {
            payment = BigDecimalUtil.add(payment.doubleValue(), orderItem.getTotalPrice().doubleValue());
            orderItemVos.add(assembleOrderItemVo(orderItem));
        }

        orderProductVo.setProductTotalPrice(payment);
        orderProductVo.setImageHost(PropertiesUtil.getProperty("ftp.server.http.prefix"));
        orderProductVo.setOrderItemVos(orderItemVos);

        return ServerResponse.createBySuccess(orderProductVo);
    }

    //直接获取订单详情
    @Override
    public ServerResponse<OrderVo> getOrderDetail(Integer userId, Long orderNo) {
        Order order = orderMapper.selectByUserIdOrderNo(userId, orderNo);
        if (order != null) {
            List<OrderItem> orderItems = orderItemMapper.selectByUserIdOrderNo(userId, orderNo);
            OrderVo orderVo = assembleOrderVo(order, orderItems);
            return ServerResponse.createBySuccess(orderVo);
        }
        return ServerResponse.createByErrorMessage("该用户没有此订单！");
    }

    //查询当前用户的订单列表
    @Override
    public ServerResponse<PageInfo<OrderVo>> list(Integer userId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<Order> orders = orderMapper.selectByUserId(userId);
        if (orders.isEmpty()) return ServerResponse.createByErrorMessage("该用户没有订单信息！");
        List<OrderVo> orderVos = Lists.newArrayList();
        for (Order order : orders) {
            List<OrderItem> orderItems = orderItemMapper.selectByUserIdOrderNo(userId, order.getOrderNo());
            orderVos.add(assembleOrderVo(order, orderItems));
        }
        PageInfo<OrderVo> pageInfo = new PageInfo(orders);
        pageInfo.setList(orderVos);
        return CollectionUtils.isEmpty(orderVos) ? ServerResponse.createByErrorMessage("查询失败！") :
                ServerResponse.createBySuccess(pageInfo);
    }

    //封装订单VO对象.
    private OrderVo assembleOrderVo(Order order, List<OrderItem> orderItems) {
        OrderVo orderVo = new OrderVo();
        orderVo.setOrderNo(order.getOrderNo());
        orderVo.setPayment(order.getPayment());
        orderVo.setPaymentType(order.getPaymentType());
        orderVo.setPaymentTypeDesc(IConst.PaymentType.getValue(order.getPaymentType()));

        orderVo.setPostage(order.getPostage());
        orderVo.setStatus(order.getStatus());
        orderVo.setStatusDesc(IConst.OrderStatus.getValue(order.getStatus()));

        orderVo.setShippingId(order.getShippingId());
        Shipping shipping = shippingMapper.selectByPrimaryKey(order.getShippingId());
        if (shipping != null) {
            orderVo.setReceiverName(shipping.getReceiverName());
            orderVo.setShippingVo(assembleShippingVo(shipping));
        }

        orderVo.setPaymentTime(DateTimeUtil.dateToStr(order.getPaymentTime()));
        orderVo.setUpdateTime(DateTimeUtil.dateToStr(order.getUpdateTime()));
        orderVo.setCreateTime(DateTimeUtil.dateToStr(order.getCreateTime()));
        orderVo.setCloseTime(DateTimeUtil.dateToStr(order.getCloseTime()));
        orderVo.setSendTime(DateTimeUtil.dateToStr(order.getSendTime()));
        orderVo.setEndTime(DateTimeUtil.dateToStr(order.getEndTime()));

        orderVo.setImageHost(PropertiesUtil.getProperty("ftp.server.http.prefix"));

        List<OrderItemVo> orderItemVos = Lists.newArrayList();
        for (OrderItem orderItem : orderItems)
            orderItemVos.add(assembleOrderItemVo(orderItem));

        orderVo.setOrderItemVos(orderItemVos);

        return orderVo;
    }

    //封装订单明细VO对象
    private OrderItemVo assembleOrderItemVo(OrderItem orderItem) {
        OrderItemVo orderItemVo = new OrderItemVo();

        orderItemVo.setOrderNo(orderItem.getOrderNo());
        orderItemVo.setProductId(orderItem.getProductId());
        orderItemVo.setProductName(orderItem.getProductName());
        orderItemVo.setProductImage(orderItem.getProductImage());
        orderItemVo.setCurrentUnitPrice(orderItem.getCurrentUnitPrice());
        orderItemVo.setQuantity(orderItem.getQuantity());
        orderItemVo.setTotalPrice(orderItem.getTotalPrice());

        orderItemVo.setCreateTime(DateTimeUtil.dateToStr(orderItem.getCreateTime()));
        orderItemVo.setUpdateTime(DateTimeUtil.dateToStr(orderItem.getUpdateTime()));

        return orderItemVo;
    }

    //封装购物车VO对象
    private ShippingVo assembleShippingVo(Shipping shipping) {
        ShippingVo shippingVo = new ShippingVo();

        shippingVo.setReceiverName(shipping.getReceiverName());
        shippingVo.setReceiverPhone(shipping.getReceiverPhone());
        shippingVo.setReceiverMobile(shipping.getReceiverMobile());
        shippingVo.setReceiverProvince(shipping.getReceiverProvince());
        shippingVo.setReceiverCity(shipping.getReceiverCity());
        shippingVo.setReceiverDistrict(shipping.getReceiverDistrict());
        shippingVo.setReceiverAddress(shipping.getReceiverAddress());
        shippingVo.setReceiverZip(shipping.getReceiverZip());

        return shippingVo;
    }

    //清空购物车
    private void cleanCart(List<Cart> carts) {
        for (Cart cart : carts)
            cartMapper.deleteByPrimaryKey(cart.getId());
    }

    //利用下面的生成订单号,计算总价==封装订单对象
    private Order assembleOrder(Integer userId, Integer shippingId, List<OrderItem> orderItems) {
        Order order = new Order();

        //设置订单号
        order.setOrderNo(generateOrderNo());

        //设置订单总价
        order.setPayment(getOrderTotalPrice(orderItems));

        order.setStatus(IConst.OrderStatus.NO_PAY.code);
        order.setPaymentType(IConst.PaymentType.ONLINE.code);
        order.setPostage(0);

        order.setUserId(userId);
        order.setShippingId(shippingId);

        return order;
    }

    //生成订单号
    private long generateOrderNo() {
        long time = System.currentTimeMillis();
        return time + new Random().nextInt(100);
    }

    //计算这个订单的总价.
    private BigDecimal getOrderTotalPrice(List<OrderItem> orderItems) {
        BigDecimal payment = new BigDecimal("0");

        for (OrderItem orderItem : orderItems) {
            payment = BigDecimalUtil.add(payment.doubleValue(), orderItem.getTotalPrice().doubleValue());
        }
        return payment;
    }

    //通过用户ID和勾选的购物车商品封装一个订单明细的集合.
    private ServerResponse<List<OrderItem>> getCartOrderItems(Integer userId, List<Cart> carts) {
        List<OrderItem> orderItems = Lists.newArrayList();

        if (CollectionUtils.isEmpty(carts))
            return ServerResponse.createByErrorMessage("购物车为空!");

        //校验购物车内商品在售状态及库存是否足够并封装OrderItem
        for (Cart cart : carts) {
            OrderItem orderItem = new OrderItem();
            //获取单个购物车中的商品信息
            Product product = productMapper.selectByPrimaryKey(cart.getProductId());
            //判定该商品是否在售
            if (product.getStatus() != IConst.ProductStatus.ON_SALE.CODE)
                return ServerResponse.createByErrorMessage("产品<" + product.getName() + ">不是在售状态!");

            //校验库存,这里最开始我认为因为购物车页面本身会一直调用数据库查询,所以不用验证.
            //但是后来想到,由于有很多人在同时购买一个商品,在这段时间内,可能商品已经被卖掉一部分.
            //而且按照这样的设计,在添加商品到购物车的过程中并没有对数据库中的商品库存进行相应的减少.
            //于是,到底在什么时候才会调用sql对商品库存进行减少呢,是这里创建订单后,还是付款完成后?
            if (cart.getQuantity() > product.getStock())
                return ServerResponse.createByErrorMessage("产品<" + product.getName() + ">库存不足!");

            orderItem.setUserId(userId);
            orderItem.setProductId(product.getId());
            orderItem.setProductName(product.getName());
            orderItem.setProductImage(product.getMainImage());
            orderItem.setCurrentUnitPrice(product.getPrice());
            orderItem.setQuantity(cart.getQuantity());
            orderItem.setTotalPrice(BigDecimalUtil.multiply(product.getPrice().doubleValue(), cart.getQuantity()));

            orderItems.add(orderItem);

            //这里老师选择重新创建private方法来减少产品库存,但是这样又要重新遍历订单明细集合访问商品数据表,感觉有点浪费.
            //所以我个人选择在这里直接进行商品库存的减少,这样不好的地方在于,如果订单最终生成错误,商品库存已经减少了.
            //但是这个问题貌似可以通过事务处理来解决,毕竟这个方法必然是需要事务处理的.
            Product tempProduct = new Product();
            tempProduct.setId(product.getId());
            tempProduct.setStock(product.getStock() - cart.getQuantity());
            productMapper.updateByPrimaryKeySelective(tempProduct);
        }
        return CollectionUtils.isEmpty(orderItems) ? ServerResponse.createByErrorMessage("生成订单明细集合失败!") : ServerResponse.createBySuccess(orderItems);
    }

    //后端管理员方法
    //管理员查询订单列表
    @Override
    public ServerResponse<PageInfo<OrderVo>> managerList(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<Order> orders = orderMapper.selectAll();
        if (orders.isEmpty()) return ServerResponse.createByErrorMessage("没有订单信息！");
        List<OrderVo> orderVos = Lists.newArrayList();
        for (Order order : orders) {
            List<OrderItem> orderItems = orderItemMapper.selectByOrderNo(order.getOrderNo());
            orderVos.add(assembleOrderVo(order, orderItems));
        }
        PageInfo<OrderVo> pageInfo = new PageInfo(orders);
        pageInfo.setList(orderVos);
        return CollectionUtils.isEmpty(orderVos) ? ServerResponse.createByErrorMessage("查询失败！") :
                ServerResponse.createBySuccess(pageInfo);
    }

    @Override
    public ServerResponse<OrderVo> managerDetail(Long orderNo) {
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order != null) {
            List<OrderItem> orderItems = orderItemMapper.selectByOrderNo(orderNo);
            OrderVo orderVo = assembleOrderVo(order, orderItems);
            return ServerResponse.createBySuccess(orderVo);
        }
        return ServerResponse.createByErrorMessage("订单不存在！");
    }

    @Test
    public void tt() {
        pay(24, 1492091061513L, "D:\\");
    }

}
